using System;
using System.Collections.Generic;
using System.Text;
using Ghasam.Business.Domain.Entity;
using Ghasam.Business.DAO;
using Spring.Transaction.Interceptor;

namespace Ghasam.Business.Services.Impl
{
    public class InternalAccountingService : IInternalAccountingService
    {
        private IInternalAccountingDao internalAccountingDao;
        private IInternalAccountDao internalAccountsDao;
        private IInternalAccountingTypeDao internalAccountingTypeDao;
        private IItemDao itemDao;
        private ISalesPersonDao salesPersonDao;

        public IInternalAccountingDao InternalAccountingDao
        {
            get { return internalAccountingDao; }
            set { internalAccountingDao = value; }
        }
        public IInternalAccountDao InternalAccountsDao
        {
            get { return internalAccountsDao; }
            set { internalAccountsDao = value; }
        }
        public IItemDao ItemDao
        {
            get { return itemDao; }
            set { itemDao = value; }
        }
        public IInternalAccountingTypeDao InternalAccountingTypeDao
        {
            get { return internalAccountingTypeDao; }
            set { internalAccountingTypeDao = value; }
        }
        public ISalesPersonDao SalesPersonDao {
            get { return salesPersonDao; }
            set { salesPersonDao = value; }
        }
        
	
        #region IInternalAccountingService Members

        public int GetCount()
        {
            return internalAccountingDao.Count();
        }

        public IList<InternalAccounting> GetAll(int pageSize, int pageNumber)
        {
            return internalAccountingDao.GetAll("ModifyStamp", true, pageSize, pageNumber);
        }

        public IList<InternalAccounting> Find(int pageSize, int pageNumber, InternalAccounting example, DateTime? StartDate, DateTime? EndDate) {
            return internalAccountingDao.Find( "ModifyStamp", true, example, StartDate, EndDate, pageSize, pageNumber );
        }

        public int CountFind(InternalAccounting example, DateTime? StartDate, DateTime? EndDate) {
            return internalAccountingDao.CountFind(example, StartDate, EndDate);
        }

        public IList<InternalAccount> GetAccounts()
        {
            return internalAccountsDao.FindAll();
        }

        public InternalAccount GetAccount(int accountId)
        {
            return internalAccountsDao.FindById(accountId);
        }

        public Item GetItem(int itemId)
        {
            return itemDao.FindById(itemId);
        }

        public IList<Item> FindItemByNameLike(string name) {
            return itemDao.FindByNameLike(name);
        }

        public Item FindItemByName(string name) {
            return itemDao.FindByName(name);
        }

        public InternalAccountingType GetInternalAccountingType(int accountingType)
        {
            return internalAccountingTypeDao.FindById(accountingType);
        }

        public IList<InternalAccountingType> GetInternalAccountingTypes()
        {
            return internalAccountingTypeDao.FindAll();
        }

        public IList<Item> GetItems()
        {
            return itemDao.FindAll();
        }

        [Transaction(ReadOnly = false)]
        public void PersistItem(Item item)
        {
            itemDao.SaveOrUpdate(item);
        }

        [Transaction(ReadOnly = false)]
        public void NewInternalAccounting(InternalAccounting accounting)
        {
            if (!accounting.Paid.Value)
            {
                accounting.SalesPerson.Balance = (accounting.SalesPerson.Balance + accounting.Debit.Value) - accounting.Credit.Value;
                accounting.SalesPerson.ModifyStamp = DateTime.Now;
            }

            internalAccountingDao.SaveOrUpdate(accounting);
        }

        [Transaction(ReadOnly = false)]
        public void NewInternalAccount(InternalAccount internalAccount) {
            internalAccount.CreateDate = DateTime.Now;
            internalAccount.ModifyStamp = DateTime.Now;

            internalAccountsDao.SaveOrUpdate(internalAccount);
        }

        [Transaction(ReadOnly = false)]
        public void DeleteInternalAccounting(InternalAccounting accounting) {

            // if Accounting not paid we should rollback balance update of sales person
            if (!accounting.Paid.Value) {
                accounting.SalesPerson.Balance = (accounting.SalesPerson.Balance - accounting.Debit.Value) + accounting.Credit.Value;
                accounting.SalesPerson.ModifyStamp = DateTime.Now;
                salesPersonDao.SaveOrUpdate(accounting.SalesPerson);
            }

            InternalAccountingDao.Delete(accounting);
        }

        [Transaction(ReadOnly=false)]
        public void DeleteInternalAccounting (int accountingId) {
            this.DeleteInternalAccounting(internalAccountingDao.FindById(accountingId));
        }

        public IList<InternalAccounting> InternalAccountingReport(Item item, SalesPerson salesPerson, InternalAccount account, DateTime? accountingStartDate, DateTime? accountingEndDate, int[] formal) {
            return InternalAccountingDao.InternalAccountingReport(item, salesPerson, account, accountingStartDate, accountingEndDate, formal);
        }

        public IList<InternalAccounting> SortInternalAccounting(int pageSize, int pageNumber, InternalAccounting example, DateTime? StartDate, DateTime? EndDate, string param, bool asc)
        {
            return InternalAccountingDao.SortInternalAccounting("ModifyStamp", true, example, StartDate, EndDate, pageSize, pageNumber, param, asc);
        }

        public InternalAccounting GetInternalAccounting(int id)
        {
            return internalAccountingDao.FindById(id);
        }

        #endregion
    }
}
